#pragma once

#include "task_base.h"
#include "application/vehicle/vehicle_service.h"
#include "application/map/map_application_service.h"
#include "application/dispatcher/dispatcher_service.h"
#include "application/map/park/park_point.h"
#include <memory>
#include <string>
#include <chrono>

namespace application {
namespace task {

/**
 * @brief 泊车任务 - AGV前往指定泊车点或自动申请泊车点
 * @details 对应三方代码中的 TaskPark (task_park.cpp)
 *
 *          核心流程（参考 task_park.cpp:11-107）：
 *
 *          Init阶段：
 *          1. 检查是否已有泊车点指针（process->park_ptr_）
 *          2. 如果没有，从 MapRecourse.park_manager 申请泊车点（reqPark）
 *          3. 预占用泊车区域（park->preOccupy）
 *          4. 将区域添加到任务上下文的区域列表（process->area_list.append）
 *          5. 设置 status = StatusRecalculation（需要重新计算路径）
 *          6. 如果已有泊车点，直接进入 Run 阶段
 *
 *          Run阶段：
 *          1. 检查 AGV 是否到达泊车点（current_station == park_ptr->adv_point_.instanceName）
 *          2. 检查导航状态是否完成（task_status == 4 || 5）
 *          3. 到达后进入 Cleanup 阶段
 *
 *          Cleanup阶段：
 *          1. 进入下一个子任务（StageNext）
 */
class ParkTask : public SubTaskBase {
public:
    /**
     * @brief 构造函数
     * @param vehicleService 车辆服务
     * @param mapService 地图服务
     * @param logger 日志记录器
     * @param parkingStation 指定泊车点ID（空表示自动申请）
     * @param floor 楼层（-1表示使用AGV当前楼层）
     */
    ParkTask(
        std::shared_ptr<vehicle::VehicleService> vehicleService,
        std::shared_ptr<MapApplicationService> mapService,
        std::shared_ptr<dispatcher::DispatcherService> dispatcherService,
        std::shared_ptr<kernel::ILogger> logger,
        const std::string& parkingStation = "",
        int floor = -1
    );

    ~ParkTask() override = default;

    // SubTaskBase 接口实现
    kernel::task::TaskStage init(TaskContext& ctx) override;
    kernel::task::TaskStage run(TaskContext& ctx) override;
    kernel::task::TaskStage cleanup(TaskContext& ctx) override;

    kernel::task::TaskType getType() const override {
        return kernel::task::TaskType::Park;
    }

    std::string getDescription() const override {
        if (m_allocatedParkPoint) {
            return "Park at: " + m_allocatedParkPoint->getPointId().toStdString();
        }
        return "Park at: " +
               (m_parkingStation.empty() ? "auto" : m_parkingStation);
    }

private:
    std::shared_ptr<vehicle::VehicleService> m_vehicleService;
    std::shared_ptr<MapApplicationService> m_mapService;
    std::shared_ptr<dispatcher::DispatcherService> m_dispatcherService;

    // 指定的泊车点ID（空表示自动申请）
    std::string m_parkingStation;

    // 楼层
    int m_floor;

    // 申请到的泊车点（对应三方代码的 park_ptr_）
    std::shared_ptr<park::ParkPoint> m_allocatedParkPoint;

    // 任务开始时间
    std::chrono::system_clock::time_point m_startTime;

    /**
     * @brief 请求泊车点（对应三方代码 task_park.cpp:18-33）
     * @param ctx 任务上下文
     * @return 是否成功申请
     */
    bool requestParkingPoint(TaskContext& ctx);

    /**
     * @brief 检查是否到达泊车点（对应三方代码 task_park.cpp:91-96）
     * @param ctx 任务上下文
     * @return 是否到达
     */
    bool hasArrivedAtParkingPoint(const TaskContext& ctx) const;

    /**
     * @brief 解析目标楼层
     */
    int resolveTargetFloor(const TaskContext& ctx) const;
};

} // namespace task
} // namespace application
